/**
 * 供详情页使用
 */
import {reactive, Ref, computed, onBeforeMount, ref, ComputedRef} from 'vue'
import {ColumnInfo, ColumnOption, FilterInfo} from '../defs/comm'
import _ from 'lodash'
import i18n from '../i18n/i18n'

import {getCurrentInstance} from 'vue'

const {t} = i18n.global

enum PageMode {
  View = 'view',
  Create = 'create',
  Edit = 'edit'
}

// Detail相关信息定义(reactive)
interface DetailInfo {
  // 详情页的条目ID，从route中获取
  itemId: string
  pageMode?: string | null
}

// Detail相关状态
interface DetailStatus {
  isViewMode: ComputedRef<boolean>
  isCreateMode: ComputedRef<boolean>
  isEditMode: ComputedRef<boolean>
  isCreateOrEditMode: ComputedRef<boolean>
  isViewOrEditMode: ComputedRef<boolean>
  pageSubTitle: ComputedRef<string>
}

// Detail的明细列表的辅助方法，对于详情页的明细列表，处理方式相当不统一，对此hooks只提供了一些帮助方法，不统一管理columnsInfo等信息
interface DetailLinesAssist {
  saveDetailColOptions: (tableId: string, colOptions: ColumnOption[]) => void
  saveDetailFilterOptions: (tableId: string, visibleFilterOptions: string[]) => void
  saveDetailPageSize: (tableId: string, pageSize: number) => void
  saveDetailSearchBarVisibility: (tableId: string, searchBarVisibility: boolean) => void
  loadDetailColOptions: (tableId: string, defColumnsInfo: ColumnInfo[]) => [ColumnInfo[], string[]]
  loadDetailFilterOptions: (tableId: string, filtersDefine: Record<string, FilterInfo>) => void
  loadDetailPageSize: (tableId: string) => number
  loadDetailSearchBarVisibility: (tableId: string) => void
}

// 跳转方法
interface DetailNav {
  goBackToList: () => void,
  goViewMode: () => void,
  goEditMode: () => void,
  cancelSubmit: () => void,
  doneEdit: () => void
}

// Detail页返回定义
interface DetailSuite {
  //Detail相关信息(reactive)
  detailInfo: DetailInfo
  //Detail相关状态
  detailStatus: DetailStatus
  //Detail跳转导航
  detailNav: DetailNav
  //明细列表的辅助方法
  dlAssist: DetailLinesAssist
}

export function useDetailHelper(
  // 页面名称，通常与routeName相同
  pageName: string,
  //表单(reactive)，对hooks来说只是在create的时候用defFormDataForCreate来给form初始化一些值
  form: Record<string, any> | null,
  //新建时默认的表单参数
  defFormDataForCreate: Record<string, any> | null,
  // 对应列表页的名称
  listRouteName: string | null,
  // 查看模式路由名称
  viewModeRouteName: string | null,
  // 新建模式路由名称
  createModeRouteName: string | null,
  // 编辑模式路由名称
  editModeRouteName: string | null,
  //加载数据，初始时以及进入view模式后会用此方法load数据
  loadModelData: () => void,
  //显示在banner上的错误信息
  serverErrorMessage: Ref<string> | null)
  : DetailSuite {

  // region 详情页信息
  const detailInfo: DetailInfo = reactive({
    itemId: '',
    pageMode: ''
  })
  // endregion

  // region 详情页状态
  const pageMode = ref('')
  // 判断页面模式是否为查看
  const isViewMode = computed(() => pageMode.value === PageMode.View)
  // 判断页面模式是否为新建
  const isCreateMode = computed(() => pageMode.value === PageMode.Create)
  // 判断页面模式是否为编辑
  const isEditMode = computed(() => pageMode.value === PageMode.Edit)
  // 判断页面模式是否为新建或编辑(修改模式)
  const isCreateOrEditMode = computed(() => pageMode.value === PageMode.Create || pageMode.value === PageMode.Edit)
  // 判断页面模式是否为查看或编辑(条目已存在)
  const isViewOrEditMode = computed(() => pageMode.value === PageMode.View || pageMode.value === PageMode.Edit)
  // 页面副标题
  const pageSubTitle = computed(() => {
    switch (pageMode.value) {
      case PageMode.View:
        return t('详情')
      case PageMode.Create:
        return t('新建')
      case PageMode.Edit:
        return t('编辑')
      default:
        return ''
    }
  })

  const detailStatus: DetailStatus = {
    isViewMode,
    isCreateMode,
    isEditMode,
    isCreateOrEditMode,
    isViewOrEditMode,
    pageSubTitle
  }
  // endregion

  // region 详情页跳转导航相关方法
  // 回到列表页
  const goBackToList = function () {
    if (!listRouteName) {
      console.warn('detailHelper: listRouteName未正确设置')
      return
    }
    void $f.router.push({
      name: listRouteName,
      state: { keepFpsSession: 'true' },
    })
  }

  // 页面转到查看模式(取消编辑)
  const goViewMode = function () {
    if (!viewModeRouteName) {
      console.warn('detailHelper: viewModeRouteName未正确设置')
      return
    }
    if (serverErrorMessage) {
      serverErrorMessage.value = ''
    }
    pageMode.value = PageMode.View
    void $f.router.push({
      name: viewModeRouteName,
      params: {itemId: detailInfo.itemId}
    })
    loadModelData()
  }

  // 页面转到编辑模式(转入编辑)
  const goEditMode = function () {
    if (!editModeRouteName) {
      console.warn('detailHelper: editModeRouteName未正确设置')
      return
    }
    pageMode.value = PageMode.Edit
    void $f.router.push({
      name: editModeRouteName,
      params: {itemId: detailInfo.itemId}
    })
  }

  // 取消新建/编辑(可能返回列表，也可能进入查看)
  const cancelSubmit = function () {
    if (isFromList) {
      goBackToList()
    } else {
      goViewMode()
    }
  }

  // 完成编辑提交(可能返货列表，也可能进入查看)
  const doneEdit = function () {
    if (isFromList) {
      goBackToList()
    } else {
      goViewMode()
    }
  }

  const detailNav: DetailNav = {
    goBackToList,
    goViewMode,
    goEditMode,
    cancelSubmit,
    doneEdit
  }
  // endregion

  // region 详情页列表有关的帮助方法
  // 详情页中的数据表列选项的key
  const getDetailColOptionsKey = function (tableId: string) {
    return pageName + '_tbcolopt_' + tableId
  }

  // 详情页中的查询条选项的key
  const getDetailVisibleFilterOptionsKey = function (tableId: string) {
    return pageName + '_filteropt_' + tableId
  }

  // 详情页中的每页条数的key
  const getDetailPageSizeLocalStorageKey = function (tableId: string) {
    return pageName + '_pagesize_' + tableId
  }

  // 详情页中的搜索条是否显示的key
  const getDetailSearchBarVisibilityKey = function (tableId: string) {
    return pageName + '_sbvisibility_' + tableId
  }

  // 保存详情页中的数据表列选项的帮助方法
  const saveDetailColOptions = function (tableId: string, colOptions: ColumnOption[]) {
    window.localStorage.setItem(getDetailColOptionsKey(tableId), JSON.stringify(colOptions))
  }

  // 保存详情页中的查询条选项的帮助方法
  const saveDetailFilterOptions = function (tableId: string, visibleFilterOptions: string[]) {
    window.localStorage.setItem(getDetailVisibleFilterOptionsKey(tableId), JSON.stringify(visibleFilterOptions))
  }

  // 保存详情页中的每页条数的帮助方法
  const saveDetailPageSize = function (tableId: string, pageSize: number) {
    window.localStorage.setItem(getDetailPageSizeLocalStorageKey(tableId), pageSize.toString())
  }

  // 保存详情页中的搜索条是否显示的帮助方法
  const saveDetailSearchBarVisibility = function (tableId: string, searchBarVisibility: boolean) {
    window.localStorage.setItem(getDetailSearchBarVisibilityKey(tableId), searchBarVisibility.toString())
  }

  // 尝试根据tableId从localStorage中调出列的选项信息，返回一个数组，数组第一个元素是columnsInfo，第二个元素是visibleColumns
  // 注：通常只在created周期函数里调用一次
  const loadDetailColOptions = function (tableId: string, defColumnsInfo: ColumnInfo[]): [ColumnInfo[], string[]] {
    let columnsInfoRes: ColumnInfo[]
    let visibleColumnsRes: string[]
    const tableColOptionsJson = window.localStorage.getItem(getDetailColOptionsKey(tableId))
    if (tableColOptionsJson) {
      const tableColOptions = JSON.parse(tableColOptionsJson) as ColumnOption[]
      columnsInfoRes = $f.misc.sortByKeys(defColumnsInfo, 'name', _.map(tableColOptions, 'name')) as ColumnInfo[]
      visibleColumnsRes = _.map(
        _.reject(tableColOptions, function (o) {
          return !o.visible
        }),
        'name'
      )
    } else {
      columnsInfoRes = defColumnsInfo
      visibleColumnsRes = _.map(
        _.reject(defColumnsInfo, function (o) {
          return !o.defVisible
        }),
        'name'
      )
    }
    return [columnsInfoRes, visibleColumnsRes]
  }

  // 尝试根据tableId从localStorage中调出查询条选项，无返回值，直接修改filterOptionList数组中的对象的属性
  // 注：通常只在created周期函数里调用一次
  const loadDetailFilterOptions = function (tableId: string, filtersDefine: Record<string, FilterInfo>) {
    const visibleFilterOptionsJson = window.localStorage.getItem(getDetailVisibleFilterOptionsKey(tableId))
    if (visibleFilterOptionsJson) {
      const visibleFilterOptions = JSON.parse(visibleFilterOptionsJson) as string[]
      _.forEach(filtersDefine, (value, key) => {
        value.show = _.indexOf(visibleFilterOptions, key) >= 0
      })
    }
  }

  // 尝试根据tableId从localStorage中调出每页条数，返回pageSize值
  const loadDetailPageSize = function (tableId: string) {
    const pageSizeJson = window.localStorage.getItem(getDetailPageSizeLocalStorageKey(tableId))
    if (pageSizeJson) {
      const pageSize = parseInt(pageSizeJson)
      if (Number.isInteger(pageSize)) {
        return pageSize
      }
    }
    return 40
  }

  // 尝试根据tableId从localStorage中调出搜索条是否显示，返回bool值
  const loadDetailSearchBarVisibility = function (tableId: string): boolean {
    return window.localStorage.getItem(getDetailSearchBarVisibilityKey(tableId)) != 'false'
  }

  const dlAssist: DetailLinesAssist = {
    saveDetailColOptions,
    saveDetailFilterOptions,
    saveDetailPageSize,
    saveDetailSearchBarVisibility,
    loadDetailColOptions,
    loadDetailFilterOptions,
    loadDetailPageSize,
    loadDetailSearchBarVisibility
  }
  // endregion

  // region 加载时自动执行部分
  // 尝试从router判断页面属于什么状态
  const routeName = $f.router.currentRoute.value.name as string
  if (routeName === viewModeRouteName) {
    pageMode.value = PageMode.View
  } else if (routeName === createModeRouteName) {
    pageMode.value = PageMode.Create
  } else if (routeName === editModeRouteName) {
    pageMode.value = PageMode.Edit
  } else {
    console.error('detailHelper: 详情页routeName不被识别 - ' + routeName)
    $f.errorState.value = 1
  }
  //是否来自列表
  const isFromList = history.state.isFromList==='true'

  if (isViewOrEditMode.value) {
    detailInfo.itemId = $f.router.currentRoute.value.params.itemId as string
    onBeforeMount(() => {
      loadModelData()
    })
  }
  if (isCreateMode.value && form && defFormDataForCreate) {
    _.forEach(defFormDataForCreate, (value, key) => {
      form[key] = value
    })
  }
  // endregion

  return {
    detailInfo,
    detailStatus,
    detailNav,
    dlAssist
  }
}
